package serverSide;

import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;

import static serverSide.Server.*;
import clientSide.Player;
import org.json.simple.JSONObject;

public class GameController {
	public static final Object[] games = {"TicTacToi", "game01(not implemented yet)", };
	private static HashMap<Integer, String> requests = new HashMap<Integer, String>();
	public static ArrayList<Game> concurrentGames = new ArrayList<Game>();
	
	public static JSONObject gameRequested(JSONObject in) {
		JSONObject out = new JSONObject();
		out.put(SUBJECT_KEY, SUBJECT_VALUE_GAMEREQUEST);
		out.put(SUBJECT_GAMEREQUEST_KEY_TYPE, SUBJECT_GAMEREQUEST_VALUE_TICTACTOI);
		
		String username = (String)in.get(SUBJECT_GAMEREQUEST_KEY_USER);
		Integer gameType = new Integer((int)in.get(SUBJECT_GAMEREQUEST_KEY_TYPE));
		
		if(requests.get(gameType) == null) {
			requests.put(gameType, username);
			out.put(SUBJECT_GAMEREQUEST_KEY_STATE, SUBJECT_GAMEREQUEST_VALUE_WAIT);
		} else {
			out.put(SUBJECT_GAMEREQUEST_KEY_STATE, SUBJECT_GAMEREQUEST_VALUE_GO);
			out.put(SUBJECT_GAMEREQUEST_KEY_PLAYER1, requests.get(gameType));
			out.put(SUBJECT_GAMEREQUEST_KEY_PLAYER2, username);
			
			concurrentGames.add(new Game(requests.get(gameType), username, gameType));
			
			requests.remove(gameType);
		}
		
		return out;
	}
	
	public static JSONObject gaming(JSONObject in, String p) {
		if((int)in.get(SUBJECT_GAMING_KEY_ACTION) == SUBJECT_GAMING_VALUE_GAME) {
			Game tmpGame = null;
			for(Game g: concurrentGames)
				if(g.p1.equals(p) || g.p2.equals(p)) {
					tmpGame = g;
					break;
				}
					
			int ans = tmpGame.addAction((int)in.get(SUBJECT_GAMING_KEY_GAMEACTION),p);
			if(ans == 0)
				return in;
			
			JSONObject out = new JSONObject();
			out.put(SUBJECT_KEY, SUBJECT_VALUE_GAMING);
			out.put(SUBJECT_GAMING_KEY_ACTION, SUBJECT_GAMING_VALUE_WINNER);
			out.put(SUBJECT_GAMING_KEY_GAMEACTION, (int)in.get(SUBJECT_GAMING_KEY_GAMEACTION));
			if(ans == 1)
				out.put(SUBJECT_GAMING_KEY_WINNER, tmpGame.p1);
			if (ans == 2)
				out.put(SUBJECT_GAMING_KEY_WINNER, tmpGame.p2);
			
			return out;
		} else {
			return in;
		}
	}
	
	public static class Game {
		String p1,p2;
		int type;
		ArrayList<Socket> viewer = new ArrayList<Socket>();
		ArrayList<Integer> history1 = new ArrayList<Integer>(),
				history2 = new ArrayList<Integer>();
		
		public Game(String p1, String p2, int type) {
			this.p1 = p1;
			this.p2 = p2;
			this.type = type;
		}
		
		public void addViewer(Socket s) {
			viewer.add(s);
		}
		
		public int addAction(int i,String playerName) {
			if(p1.equals(playerName))
				history1.add(i);
			if(p2.equals(playerName))
				history2.add(i);
			
			//check
			if(history1.contains(0) && history1.contains(1) && history1.contains(2))
				return 1;
			if(history1.contains(3) && history1.contains(4) && history1.contains(5))
				return 1;
			if(history1.contains(6) && history1.contains(7) && history1.contains(8))
				return 1;
			if(history1.contains(0) && history1.contains(4) && history1.contains(8))
				return 1;
			if(history1.contains(6) && history1.contains(4) && history1.contains(2))
				return 1;
			if(history1.contains(0) && history1.contains(3) && history1.contains(6))
				return 1;
			if(history1.contains(1) && history1.contains(4) && history1.contains(7))
				return 1;
			if(history1.contains(2) && history1.contains(5) && history1.contains(8))
				return 1;
			
			if(history2.contains(0) && history2.contains(1) && history2.contains(2))
				return 2;
			if(history2.contains(3) && history2.contains(4) && history2.contains(5))
				return 2;
			if(history2.contains(6) && history2.contains(7) && history2.contains(8))
				return 2;
			if(history2.contains(0) && history2.contains(4) && history2.contains(8))
				return 2;
			if(history2.contains(6) && history2.contains(4) && history2.contains(2))
				return 2;
			if(history2.contains(0) && history2.contains(3) && history2.contains(6))
				return 2;
			if(history2.contains(1) && history2.contains(4) && history2.contains(7))
				return 2;
			if(history2.contains(2) && history2.contains(5) && history2.contains(8))
				return 2;
			
			return 0;
		}
	}
}
